<?php

/**new
 * @file classes/journal/DMTKDAO.inc.php
 *
 * Copyright (c) 2003-2012 John Willinsky
 * Edit by: Ngoc Diệp
 *for retrieving and modifying DMTK objects.
 */


define('DMTK_FIELD_MATK', 'matk');
define('DMTK_FIELD_TENTK', 'tentk');
define('DMTK_FIELD_NONE', null);



import ('classes.acct.DMTK');

class DMTKDAO extends DAO {
	var $cache;
	function &_getCache($journalId) {
		static $settingCache;
		if (!isset($settingCache)) {
			$settingCache = array();
		}
		if (!isset($settingCache[$journalId])) {
			$cacheManager =& CacheManager::getManager();
			$settingCache[$journalId] =& $cacheManager->getFileCache(
				"DMTK", $journalId,
				array($this, '_cacheMiss')
			);

			$cacheTime = $settingCache[$journalId]->getCacheTime();
			$result =& $this->retrieve("SELECT last_modified FROM filecache WHERE filename = 'dmtk' LIMIT 1");
			if ($result->RecordCount() > 0 ){
				$row =& $result->GetRowAssoc(false);
				if (strtotime($row['last_modified']) > $cacheTime)
					$settingCache[$journalId]->flush();
			}

		}
		return $settingCache[$journalId];
	}

	/**
	 * Retrieve a journal setting value.
	 * @param $journalId int
	 * @param $name string
	 * @param $locale string optional
	 * @return mixed
	 */
	function &getSetting($journalId, $name, $locale) {
		$cache =& $this->_getCache($journalId);
		$returner = $cache->get($name);

		if ($locale !== null) {
			if (!isset($returner[$locale]) || !is_array($returner)) {
				unset($returner);
				$returner = null;
				return $returner;
			}
			return $returner[$locale];
		}
		return $returner;
	}

	function _cacheMiss(&$cache, $id) {
		$settings =& $this->getDMTKSettings($cache->getCacheId());
		if (!isset($settings[$id])) {
			$cache->setCache($id, null);
			return null;
		}
		return $settings[$id];
	}

	/**
	 * Retrieve and cache all settings for a journal.
	 * @param $journalId int
	 * @return array
	 */
	function &getDMTKSettings($journalId) {
		$journalSettings = array();
		$result =& $this->retrieve(
				"SELECT * FROM DMTK WHERE MATK !='' ORDER BY MATK");

		$sectionsIterator = new DAOResultFactory($result, $this, '_returnDMTKFromRow');

		$sections = "";
		$journalSettings['matk'] = array();

		while (($section =& $sectionsIterator->next())) {
			$pma = trim($section->getmatk());
			$pten = trim($section->gettentk());
			$journalSettings['matk']["_".$pma] = $pma."::".$pten;
		}

		$cache =& $this->_getCache($journalId);
		$cache->setEntireCache($journalSettings) ;
		return $journalSettings;
	}

	function &zgetDMTKSettings($journalId) {
		$journalSettings = array();
		//$journalSettings['tkdv']="";
		//$journalSettings['tkcp']="";

		$result =& $this->retrieve(
				"SELECT * FROM DMTK WHERE MATK !='' ORDER BY MATK");

		$sectionsIterator = new DAOResultFactory($result, $this, '_returnDMTKFromRow');
		$sections = "";
		$bolds = "<b>";
		$bolde = "</b>";
		$alinke  = "</a>";

		//$alinka = "<a href='javascript:void(0);' onclick='jgetmaTK(this.text)'>";
		$alinka = "<a href='javascript:void(0);' onclick='jgetmaTK(this.text";
		while (($section =& $sectionsIterator->next())) {
			$pma = strtoupper($section->getmatk());
			$pten = $section->gettentk();
			$ploaitk = $section->getloaitk();
			//$journalSettings['tracuu'] .= $bolds.$alinka.$pma.$alinke.$bolde."-".$pten."<br>";

			$journalSettings['tracuu'] .= $bolds.$alinka.',"'.$pten.'"'.")'>".$pma.$alinke.$bolde."-".$pten."<br>";

			$journalSettings['matk'] .= $pma."-";
			if ($ploaitk == "DV")
				$journalSettings['tkdv'] .= $pma."-";
			else if ($ploaitk == "CP")
				$journalSettings['tkcp'] .= $pma."-";


		}
		if ($journalSettings['tkcp'] == null)
			$journalSettings['tkcp'] = "";

		$cache =& $this->_getCache($journalId);
		$cache->setEntireCache($journalSettings) ;
		return $journalSettings;
	}


	function updatecdtk($bcc){
		//var_dump($bcc);
		$query = "update dmtk set cdtk = 1 where matk in (". $bcc. ")";
		$result =& $this->retrieve($query) ;
		$query = "update dmtk set cdtk = 0 where matk not in (". $bcc. ")";
		$result =& $this->retrieve($query) ;

	}

	function &getDS_CDTK() {
		{
			$result =& $this->retrieve(
				'SELECT * FROM DMTK WHERE CDTK=1 and char_length(matk)>1 ORDER BY matk'
			);
		}

		$sectionsIterator = new DAOResultFactory($result, $this, '_returnDMTKFromRow');

		$sections = $returner ;
		while (($section =& $sectionsIterator->next())) {
			$pmatk = $section->getmatk();
			$ptentk = $section->gettentk();
			$sections[$pmatk]['tk'] = $pmatk."-".$ptentk;
			unset($section);
		}
		return $sections;
	}

	function &getDSMATK($MATK) {
		$MATK = "$MATK%";
		if (isset($MATK))
		{
			$result =& $this->retrieve(
				'SELECT * FROM DMTK WHERE LOWER(matk) LIKE LOWER(?) ORDER BY matk', $MATK
			);
		}
		else
			$result =& $this->retrieve(
				"SELECT * FROM DMTK WHERE matk !='' ORDER BY matk");

		$sectionsIterator = new DAOResultFactory($result, $this, '_returnDMTKFromRow');

		$sections = $returner ;
		while (($section =& $sectionsIterator->next())) {
			$pmatk = $section->getmatk();
			$ptentk = $section->gettentk();
			$sections[$pmatk] = $pmatk."-".$ptentk;
			unset($section);
		}
		return $sections;
	}
	//////////////

	function &getDSMATENTK($MATK) {
		

		if (isset($MATK))
		{
			$MATK = "$MATK%";
			$result =& $this->retrieve(
				'SELECT * FROM DMTK WHERE LOWER(matk) LIKE LOWER(?) ORDER BY matk', $MATK
			);
		}
		else
			$result =& $this->retrieve(
				"SELECT * FROM DMTK WHERE char_length(matk)>1 ORDER BY matk");

		$sections = $returner ;
		while (!$result->EOF) {
			$rows = $result->GetRowAssoc(false);
			$pmatk = $rows['matk'];
			$ptentk = $rows['tentk'];
			$sections[$pmatk."-".$ptentk] = $pmatk."-".$ptentk;
			unset($section);
			$result->moveNext();
		}
		return $sections;
	}
	//////////////

	function &getDMTK($MATK, $DaoFac = false, $combo = false) {
		if (isset($MATK))
			$result =& $this->retrieve(
				'SELECT * FROM DMTK WHERE MATK = ? ORDER BY matk', $MATK
			);
		else
			$result =& $this->retrieve(
				"SELECT * FROM DMTK WHERE matk !='' ORDER BY matk");

		$sectionsIterator = new DAOResultFactory($result, $this, '_returnDMTKFromRow');

		if ($DaoFac)
			return $sectionsIterator;
		else if (!$combo)
		{
			$returner = null;
			if ($result->RecordCount() != 0) {
				$returner =& $this->_returnDMTKFromRow($result->GetRowAssoc(false));
			}

			$result->Close();
			unset($result);
			return $returner;
		}

		$sections = $returner ;
		while (($section =& $sectionsIterator->next())) {
			$sections[$section->getmatk()] = $section->getmatk()."-".$section->gettentk();
			unset($section);
		}
		return $sections;
	}


	/////////////
	function &_returnDMTKFromRow(&$row) {
		$DMTK = new DMTK($row['matk'], $row['tentk'], $row['loaitk']);
		$DMTK->setcdtk($row['cdtk']);
		return $DMTK;
	}


	function &getDMTKSearch($searchType = null, $search = null, $searchMatch = null) {

		$paramArray = array();
		$searchSql = '';

		$searchTypeMap = array(
			DMTK_FIELD_MATK => 'dmtk.matk',
			DMTK_FIELD_TENTK => 'dmtk.tentk'

		);

		if (!empty($search) && isset($searchTypeMap[$searchType])) {
			$fieldName = $searchTypeMap[$searchType];
			switch ($searchMatch) {
				case 'is':
					$searchSql = "AND LOWER($fieldName) = LOWER(?)";
					$paramArray[] = $search;
					break;
				case 'contains':
					$searchSql = "AND LOWER($fieldName) LIKE LOWER(?)";
					$paramArray[] = '%' . $search . '%';
					break;
				case 'startsWith':
					$searchSql = "AND LOWER($fieldName) LIKE LOWER(?)";
					$paramArray[] = $search . '%';
					break;
			}
		}
//		elseif (!empty($search)) switch ($searchType) {
//			case USER_FIELD_USERID:
//				$searchSql = 'AND u.user_id=?';
//				$paramArray[] = $search;
//				break;
//			case USER_FIELD_INITIAL:
//				$searchSql = 'AND LOWER(u.last_name) LIKE LOWER(?)';
//				$paramArray[] = $search . '%';
//				break;
//		}

		//$searchSql .= ($sortBy?(' ORDER BY ' . $this->getSortMapping($sortBy) . ' ' . $this->getDirectionMapping($sortDirection)) : '');
		$result =& $this->retrieve(
				"SELECT * FROM DMTK WHERE matk !='' ". $searchSql. " ORDER BY matk",
			$paramArray
		);

		$returner = new DAOResultFactory($result, $this, '_returnDMTKFromRow');
		return $returner;
	}



	function deleteTKByMa($DMTKId) {
	$result =& $this->retrieve("select * from filecache where filename = 'dmtk' LIMIT 1");

	if ($result->RecordCount() == 0)
		$mysql = "INSERT INTO  filecache (`filename` ,`last_modified`) VALUES ('dmtk', '". date("Y-m-d H:i:s")."');";
	else
		$mysql = "UPDATE  filecache SET last_modified = '".date("Y-m-d H:i:s"). "' where filename = 'dmtk'";

	$this->retrieve($mysql);

	return $this->update(
			'DELETE FROM DMTK WHERE matk = ? ',
			array($DMTKId)
			);

	}






	

	/**
	 * Retrieve a DMTK by abbreviation.
	 * @param $DMTKAbbrev string
	 * @param $locale string optional
	 * @return DMTK
	 */
	function &getDMTKByAbbrev($DMTKAbbrev, $journalId, $locale = null) {
		$sql = 'SELECT s.* FROM DMTK s, DMTK_settings l WHERE l.DMTK_id = s.DMTK_id AND l.setting_name = ? AND l.setting_value = ? AND s.journal_id = ?';
		$params = array('abbrev', $DMTKAbbrev, $journalId);
		if ($locale !== null) {
			$sql .= ' AND l.locale = ?';
			$params[] = $locale;
		}

		$result =& $this->retrieve($sql, $params);

		$returner = null;
		if ($result->RecordCount() != 0) {
			$returner =& $this->_returnDMTKFromRow($result->GetRowAssoc(false));
		}

		$result->Close();
		unset($result);

		return $returner;
	}

	/**
	 * Retrieve a DMTK by title.
	 * @param $DMTKTitle string
	 * @return DMTK
	 */
	function &getDMTKByTitle($DMTKTitle, $journalId, $locale = null) {
		$sql = 'SELECT s.* FROM DMTK s, DMTK_settings l WHERE l.DMTK_id = s.DMTK_id AND l.setting_name = ? AND l.setting_value = ? AND s.journal_id = ?';
		$params = array('title', $DMTKTitle, $journalId);
		if ($locale !== null) {
			$sql .= ' AND l.locale = ?';
			$params[] = $locale;
		}

		$result =& $this->retrieve($sql, $params);

		$returner = null;
		if ($result->RecordCount() != 0) {
			$returner =& $this->_returnDMTKFromRow($result->GetRowAssoc(false));
		}

		$result->Close();
		unset($result);

		return $returner;
	}

	/**
	 * Retrieve a DMTK by title and abbrev.
	 * @param $DMTKTitle string
	 * @param $DMTKAbbrev string
	 * @param $locale string optional
	 * @return DMTK
	 */
	function &getDMTKByTitleAndAbbrev($DMTKTitle, $DMTKAbbrev, $journalId, $locale) {
		$sql = 'SELECT s.* FROM DMTK s, DMTK_settings l1, DMTK_settings l2 WHERE l1.DMTK_id = s.DMTK_id AND l2.DMTK_id = s.DMTK_id AND l1.setting_name = ? AND l2.setting_name = ? AND l1.setting_value = ? AND l2.setting_value = ? AND s.journal_id = ?';
		$params = array('title', 'abbrev', $DMTKTitle, $DMTKAbbrev, $journalId);
		if ($locale !== null) {
			$sql .= ' AND l1.locale = ? AND l2.locale = ?';
			$params[] = $locale;
			$params[] = $locale;
		}

		$result =& $this->retrieve($sql, $params);

		$returner = null;
		if ($result->RecordCount() != 0) {
			$returner =& $this->_returnDMTKFromRow($result->GetRowAssoc(false));
		}

		$result->Close();
		unset($result);

		return $returner;
	}

	/**
	 * Internal function to return a DMTK object from a row.
	 * @param $row array
	 * @return DMTK
	 */

//	/**
//	 * Get the list of fields for which data can be localized.
//	 * @return array
//	 */
//	function getLocaleFieldNames() {
//		return array('title', 'abbrev', 'policy', 'identifyType');
//	}
//
//	/**
//	 * Update the localized fields for this table
//	 * @param $DMTK object
//	 */
	function updateLocaleFields(&$DMTK) {
		$this->updateDataObjectSettings('DMTK_settings', $DMTK, array(
			'DMTK_id' => $DMTK->getId()
		));
	}

	/**
	 * Insert a new DMTK.
	 * @param $DMTK DMTK
	 */
	function insertDMTK(&$DMTK) {
		$this->update(
			'INSERT INTO DMTK
				(matk, tentk)
				VALUES
				(?, ?)',
			array(
				$DMTK->getmatk(),
				$DMTK->gettentk()
			)
		);

		$DMTK->setId($this->getInsertDMTKId());
		$this->updateLocaleFields($DMTK);
		return $DMTK->getId();
	}

	/**
	 * Update an existing DMTK.
	 * @param $DMTK DMTK
	 */
	function updateDMTK(&$DMTK) {
		$returner = $this->update(
			'UPDATE DMTK
				SET
					matk = ?,
					tentk = ?
				WHERE matk = ?',
			array(
				$DMTK->getmatk(),
				$DMTK->gettentk(),
				$DMTK->getmatk()
			)
		);
		$this->updateLocaleFields($DMTK);
		return $returner;
	}

	/**
	 * Delete a DMTK.
	 * @param $DMTK DMTK
	 */
	function deleteDMTK(&$DMTK) {
		return $this->deleteDMTKById($DMTK->getId(), $DMTK->getJournalId());
	}

	/**
	 * Delete a DMTK by ID.
	 * @param $DMTKId int
	 * @param $journalId int optional
	 */

	/**
	 * Delete DMTK by journal ID
	 * NOTE: This does not delete dependent entries EXCEPT from DMTK_editors. It is intended
	 * to be called only when deleting a journal.
	 * @param $journalId int
	 */
	function deleteDMTKByJournal($journalId) {
		$DMTK =& $this->getJournalDMTK($journalId);
		while (($DMTK =& $DMTK->next())) {
			$this->deleteDMTK($DMTK);
			unset($DMTK);
		}
	}

	/**
	 * Retrieve an array associating all DMTK editor IDs with
	 * arrays containing the DMTK they edit.
	 * @return array editorId => array(DMTK they edit)
	 */
	function &getEditorDMTK($journalId) {
		$returner = array();

		$result =& $this->retrieve(
			'SELECT s.*, se.user_id AS editor_id FROM DMTK_editors se, DMTK s WHERE se.DMTK_id = s.DMTK_id AND s.journal_id = se.journal_id AND s.journal_id = ?',
			$journalId
		);

		while (!$result->EOF) {
			$row = $result->GetRowAssoc(false);
			$DMTK =& $this->_returnDMTKFromRow($row);
			if (!isset($returner[$row['editor_id']])) {
				$returner[$row['editor_id']] = array($DMTK);
			} else {
				$returner[$row['editor_id']][] = $DMTK;
			}
			$result->moveNext();
		}

		$result->Close();
		unset($result);

		return $returner;
	}

	/**
	 * Retrieve all DMTK in which articles are currently published in
	 * the given issue.
	 * @return array
	 */
	function &getDMTKForIssue($issueId) {
		$returner = array();

		$result =& $this->retrieve(
			'SELECT DISTINCT s.*, COALESCE(o.seq, s.seq) AS DMTK_seq FROM DMTK s, published_articles pa, articles a LEFT JOIN custom_DMTK_orders o ON (a.DMTK_id = o.DMTK_id AND o.issue_id = ?) WHERE s.DMTK_id = a.DMTK_id AND pa.article_id = a.article_id AND pa.issue_id = ? ORDER BY DMTK_seq',
			array($issueId, $issueId)
		);

		while (!$result->EOF) {
			$row = $result->GetRowAssoc(false);
			$returner[] =& $this->_returnDMTKFromRow($row);
			$result->moveNext();
		}

		$result->Close();
		unset($result);

		return $returner;
	}

	/**
	 * Retrieve all DMTK for a journal.
	 * @return DAOResultFactory containing DMTK ordered by sequence
	 */
	function &getJournalDMTK($journalId, $rangeInfo = null) {
		$result =& $this->retrieveRange(
			'SELECT * FROM DMTK WHERE journal_id = ? ORDER BY seq',
			$journalId, $rangeInfo
		);

		$returner = new DAOResultFactory($result, $this, '_returnDMTKFromRow');
		return $returner;
	}

	/**
	 * Retrieve the IDs and titles of the DMTK for a journal in an associative array.
	 * @return array
	 */
	function &getDMTKTitles($journalId, $submittableOnly = false) {
		$DMTK = array();

		$DMTKIterator =& $this->getJournalDMTK($journalId);
		while (($DMTK =& $DMTKIterator->next())) {
			if ($submittableOnly) {
				if (!$DMTK->getEditorRestricted()) {
					$DMTK[$DMTK->getId()] = $DMTK->getLocalizedTitle();
				}
			} else {
				$DMTK[$DMTK->getId()] = $DMTK->getLocalizedTitle();
			}
			unset($DMTK);
		}

		return $DMTK;
	}

	/**
	 * Check if a DMTK exists with the specified ID.
	 * @param $DMTKId int
	 * @param $journalId int
	 * @return boolean
	 */
	function DMTKExists($DMTKId, $journalId) {
		$result =& $this->retrieve(
			'SELECT COUNT(*) FROM DMTK WHERE DMTK_id = ? AND journal_id = ?',
			array($DMTKId, $journalId)
		);
		$returner = isset($result->fields[0]) && $result->fields[0] == 1 ? true : false;

		$result->Close();
		unset($result);

		return $returner;
	}

	/**
	 * Sequentially renumber DMTK in their sequence order.
	 * @param $journalId int
	 */
	function resequenceDMTK($journalId) {
		$result =& $this->retrieve(
			'SELECT DMTK_id FROM DMTK WHERE journal_id = ? ORDER BY seq',
			$journalId
		);

		for ($i=1; !$result->EOF; $i++) {
			list($DMTKId) = $result->fields;
			$this->update(
				'UPDATE DMTK SET seq = ? WHERE DMTK_id = ?',
				array(
					$i,
					$DMTKId
				)
			);

			$result->moveNext();
		}

		$result->close();
		unset($result);
	}

	/**
	 * Get the ID of the last inserted DMTK.
	 * @return int
	 */
	function getInsertDMTKId() {
		return $this->getInsertId('DMTK', 'DMTK_id');
	}

	/**
	 * Delete the custom ordering of an issue's DMTK.
	 * @param $issueId int
	 */
	function deleteCustomDMTKOrdering($issueId) {
		return $this->update(
			'DELETE FROM custom_DMTK_orders WHERE issue_id = ?', $issueId
		);
	}

	/**
	 * Delete a DMTK from the custom DMTK order table.
	 * @param $issueId int
	 * @param $DMTKId int
	 */
	function deleteCustomDMTK($issueId, $DMTKId) {
		$sequence = $this->getCustomDMTKOrder($issueId, $DMTKId);

		$this->update(
			'DELETE FROM custom_DMTK_orders WHERE issue_id = ? AND DMTK_id = ?', array($issueId, $DMTKId)
		);

		// Reduce the DMTK order of every successive DMTK by one
		$this->update(
			'UPDATE custom_DMTK_orders SET seq = seq - 1 WHERE issue_id = ? AND seq > ?', array($issueId, $sequence)
		);
	}

	/**
	 * Sequentially renumber custom DMTK orderings in their sequence order.
	 * @param $issueId int
	 */
	function resequenceCustomDMTKOrders($issueId) {
		$result =& $this->retrieve(
			'SELECT DMTK_id FROM custom_DMTK_orders WHERE issue_id = ? ORDER BY seq',
			$issueId
		);

		for ($i=1; !$result->EOF; $i++) {
			list($DMTKId) = $result->fields;
			$this->update(
				'UPDATE custom_DMTK_orders SET seq = ? WHERE DMTK_id = ? AND issue_id = ?',
				array($i, $DMTKId, $issueId)
			);

			$result->moveNext();
		}

		$result->close();
		unset($result);
	}

	/**
	 * Check if an issue has custom DMTK ordering.
	 * @param $issueId int
	 * @return boolean
	 */
	function customDMTKOrderingExists($issueId) {
		$result =& $this->retrieve(
			'SELECT COUNT(*) FROM custom_DMTK_orders WHERE issue_id = ?',
			$issueId
		);
		$returner = isset($result->fields[0]) && $result->fields[0] == 0 ? false : true;

		$result->Close();
		unset($result);

		return $returner;
	}

	/**
	 * Get the custom DMTK order of a DMTK.
	 * @param $issueId int
	 * @param $DMTKId int
	 * @return int
	 */
	function getCustomDMTKOrder($issueId, $DMTKId) {
		$result =& $this->retrieve(
			'SELECT seq FROM custom_DMTK_orders WHERE issue_id = ? AND DMTK_id = ?',
			array($issueId, $DMTKId)
		);

		$returner = null;
		if (!$result->EOF) {
			list($returner) = $result->fields;
		}
		$result->Close();
		unset($result);

		return $returner;
	}

	/**
	 * Import the current DMTK orders into the specified issue as custom
	 * issue orderings.
	 * @param $issueId int
	 */
	function setDefaultCustomDMTKOrders($issueId) {
		$result =& $this->retrieve(
			'SELECT s.DMTK_id FROM DMTK s, issues i WHERE i.journal_id = s.journal_id AND i.issue_id = ? ORDER BY seq',
			$issueId
		);

		for ($i=1; !$result->EOF; $i++) {
			list($DMTKId) = $result->fields;
			$this->insertCustomDMTKOrder($issueId, $DMTKId, $i);
			$result->moveNext();
		}

		$result->close();
		unset($result);
	}

	/**
	 * INTERNAL USE ONLY: Insert a custom DMTK ordering
	 * @param $issueId int
	 * @param $DMTKId int
	 * @param $seq int
	 */
	function insertCustomDMTKOrder($issueId, $DMTKId, $seq) {
		$this->update(
			'INSERT INTO custom_DMTK_orders (DMTK_id, issue_id, seq) VALUES (?, ?, ?)',
			array(
				$DMTKId,
				$issueId,
				$seq
			)
		);
	}

	/**
	 * Move a custom issue ordering up or down, resequencing as necessary.
	 * @param $issueId int
	 * @param $DMTKId int
	 * @param $newPos int The new position (0-based) of this DMTK
	 * @param $up boolean Whether we're moving the DMTK up or down
	 */
	function moveCustomDMTKOrder($issueId, $DMTKId, $newPos, $up) {
		$this->update(
			'UPDATE custom_DMTK_orders SET seq = ? ' . ($up?'-':'+') . ' 0.5 WHERE issue_id = ? AND DMTK_id = ?',
			array($newPos, $issueId, $DMTKId)
		);
		$this->resequenceCustomDMTKOrders($issueId);
	}
}

?>
